package com.baidu.mpks.permission.service;

import com.baidu.mpks.permission.dao.PermissionDao;
import com.baidu.mpks.permission.dao.PermissionDataRoleDao;
import com.baidu.mpks.permission.dao.PermissionDataUserDao;
import com.baidu.mpks.permission.domain.Permission;
import com.baidu.mpks.permission.domain.PermissionDataRole;
import com.baidu.mpks.permission.domain.PermissionDataUser;
import com.baidu.mpks.permission.dto.AtomDataRolePermissionDto;
import com.baidu.mpks.permission.dto.AuthInfoDto;
import com.baidu.mpks.permission.dto.DataRolePermissionDto;
import com.baidu.mpks.role.service.RoleService;
import com.baidu.mpks.user.service.UserService;
import com.baidu.mpks.usergroup.dto.Resources;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class PermissionServiceImpl implements PermissionService{

    @Autowired
    RoleService roleService;
    @Autowired
    PermissionDao permissionDao;
    @Autowired
    PermissionDataRoleDao permissionDataRoleDao;
    @Autowired
    PermissionDataUserDao permissionDataUserDao;
    @Autowired
    UserService userService;
    @Value("${role-config.permission.exclude-ids:}")
    private List<Integer> excludeIds;

    public PermissionServiceImpl() {
    }

    public Map<String, Object> getPermissionList(Integer pageNum, Integer pageSize) {
        Map<String, Object> result = new HashMap();
        result.put("list", this.permissionDao.findAllExclude((pageNum - 1) * pageSize, pageSize, this.excludeIds));
        result.put("totalSize", this.permissionDao.findAllTotalExclude(this.excludeIds));
        result.put("auditList", this.permissionDao.findAllAuditExclude((pageNum - 1) * pageSize, pageSize, this.excludeIds));
        result.put("auditSize", this.permissionDao.findAllAuditTotalExclude(this.excludeIds));
        return result;
    }

    public List<Permission> findAll(Integer pageNum, Integer pageSize) {
        return this.permissionDao.findAll((pageNum - 1) * pageSize, pageSize);
    }

    public List<Permission> getPermissionListByType(List<Integer> typeList) {
        return this.permissionDao.getPermissionListByType(typeList);
    }

    public Set<String> findPermissionCodesByRoleIds(Collection<Integer> roleIds) {
        List<Permission> permissions = this.permissionDao.findByRoleIds(new ArrayList(roleIds));
        Set<String> pCodes = new LinkedHashSet();
        Iterator var4 = permissions.iterator();

        while(var4.hasNext()) {
            Permission p = (Permission)var4.next();
            pCodes.add(p.getCode());
        }

        return pCodes;
    }

    public Set<String> findPermissonCodesByUserId(String userId) {
        List<Resources> roles = this.userService.getUserAllRoles(userId);
        Set<Integer> roleIds = (Set)roles.stream().map(Resources::getId).collect(Collectors.toSet());
        return CollectionUtils.isNotEmpty(roleIds) && roleIds.contains(1) ? (Set)this.findAll(1, 1000).stream().map(Permission::getCode).collect(Collectors.toSet()) : this.findPermissionCodesByRoleIds(roleIds);
    }

    @Transactional
    public void deleteDataPermissionByDataId(AuthInfoDto authInfo) {
        String dataId = authInfo.getDataId();
        Iterator var3 = authInfo.getPermissions().iterator();

        while(var3.hasNext()) {
            AtomDataRolePermissionDto permissions = (AtomDataRolePermissionDto)var3.next();
            if (permissions.getRoleIds() != null) {
                this.permissionDataRoleDao.deleteByDataIdAndOpType(dataId, permissions.getOp());
            }

            if (permissions.getUserIds() != null) {
                this.permissionDataUserDao.deleteByDataIdAndOpType(dataId, permissions.getOp());
            }
        }

        if (authInfo.getPropList() != null && authInfo.getPropList().size() > 0) {
            Map<String, List<String>> dataRoleIdsMap = new HashMap();
            Map<String, List<String>> dataUserIdsMap = new HashMap();
            List<String> dataRoleIds = new ArrayList();
            List<String> dataUserIds = new ArrayList();
            Iterator var7 = authInfo.getPropList().iterator();

            while(var7.hasNext()) {
                DataRolePermissionDto atomProp = (DataRolePermissionDto)var7.next();
                String propId = atomProp.getDataId();
                String classPropId = dataId + "@" + propId;
                Iterator var11 = atomProp.getPermissions().iterator();

                while(var11.hasNext()) {
                    AtomDataRolePermissionDto permission = (AtomDataRolePermissionDto)var11.next();
                    if (permission.getRoleIds() != null) {
                        if (dataRoleIdsMap.get(permission.getOp()) != null) {
                            dataRoleIds = (List)dataRoleIdsMap.get(permission.getOp());
                        }

                        ((List)dataRoleIds).add(classPropId);
                        dataRoleIdsMap.put(permission.getOp(), dataRoleIds);
                    }

                    if (permission.getUserIds() != null) {
                        if (dataUserIdsMap.get(permission.getOp()) != null) {
                            dataUserIds = (List)dataUserIdsMap.get(permission.getOp());
                        }

                        ((List)dataUserIds).add(classPropId);
                        dataUserIdsMap.put(permission.getOp(), dataUserIds);
                    }
                }
            }

            var7 = dataRoleIdsMap.keySet().iterator();

            String op;
            while(var7.hasNext()) {
                op = (String)var7.next();
                if (((List)dataRoleIdsMap.get(op)).size() > 0) {
                    this.permissionDataRoleDao.deleteByDataIdsAndOpType((List)dataRoleIdsMap.get(op), op);
                }
            }

            var7 = dataUserIdsMap.keySet().iterator();

            while(var7.hasNext()) {
                op = (String)var7.next();
                if (((List)dataUserIdsMap.get(op)).size() > 0) {
                    this.permissionDataUserDao.deleteByDataIdsAndOpType((List)dataUserIdsMap.get(op), op);
                }
            }
        }

    }

    @Transactional
    public List<String> addDataPermissionByDataIdV2(AuthInfoDto authInfo) {
        List<String> result = new ArrayList();
        List propPermissionList;
        if (authInfo.getIsEncryption() == 0 || authInfo.getPermissions() != null && authInfo.getPermissions().size() > 0) {
            propPermissionList = authInfo.getPermissions();
            Iterator var4 = propPermissionList.iterator();

            label168:
            while(true) {
                AtomDataRolePermissionDto item;
                ArrayList list;
                String userId;
                Iterator var25;
                do {
                    do {
                        if (!var4.hasNext()) {
                            break label168;
                        }

                        item = (AtomDataRolePermissionDto)var4.next();
                        Set<String> roleIds = item.getRoleIds();
                        if (item.getInheritRoleIds() != null) {
                            roleIds.removeAll(item.getInheritRoleIds());
                        }

                        if (authInfo.getIsEncryption() == 0 || roleIds != null && roleIds.size() > 0) {
                            list = new ArrayList();
                            if (authInfo.getIsEncryption() == 0) {
                                PermissionDataRole atomRole = new PermissionDataRole();
                                atomRole.setDataId(authInfo.getDataId());
                                atomRole.setRoleId("all");
                                atomRole.setIdType(authInfo.getIdType());
                                atomRole.setOp(item.getOp());
                                if (!list.contains(atomRole)) {
                                    list.add(atomRole);
                                }
                            }

                            PermissionDataRole atomRole;
                            for(var25 = roleIds.iterator(); var25.hasNext(); result.add("dataId:" + atomRole.getDataId() + "_roleId:" + userId)) {
                                userId = (String)var25.next();
                                atomRole = new PermissionDataRole();
                                atomRole.setDataId(authInfo.getDataId());
                                atomRole.setRoleId(userId);
                                atomRole.setIdType(authInfo.getIdType());
                                atomRole.setOp(item.getOp());
                                if (!list.contains(atomRole)) {
                                    list.add(atomRole);
                                }
                            }

                            try {
                                this.permissionDataRoleDao.batchAdd(list);
                            } catch (DuplicateKeyException var20) {
//                                log.info("addDataPermissionByDataId duplicate roleId {}", var20.getMessage());
                            }
                        }
                    } while(item.getUserIds() == null);
                } while(item.getUserIds().size() <= 0);

                list = new ArrayList();

                PermissionDataUser atomUser;
                for(var25 = item.getUserIds().iterator(); var25.hasNext(); result.add("dataId:" + atomUser.getDataId() + "_userId:" + userId)) {
                    userId = (String)var25.next();
                    atomUser = new PermissionDataUser();
                    atomUser.setDataId(authInfo.getDataId());
                    atomUser.setUserId(userId);
                    atomUser.setIdType(authInfo.getIdType());
                    atomUser.setOp(item.getOp());
                    if (!list.contains(atomUser)) {
                        list.add(atomUser);
                    }
                }

                try {
                    this.permissionDataUserDao.batchAdd(list);
                } catch (DuplicateKeyException var19) {
//                    log.info("addDataPermissionByDataId duplicate userId {}", var19.getMessage());
                }
            }
        }

        if (authInfo.getPropList() != null && authInfo.getPropList().size() > 0) {
            propPermissionList = authInfo.getPropList();
            String classId = authInfo.getDataId();
            Iterator var22 = propPermissionList.iterator();

            label132:
            while(var22.hasNext()) {
                DataRolePermissionDto dataRolePermissionDto = (DataRolePermissionDto)var22.next();
                String propId = dataRolePermissionDto.getDataId();
                String classPropId = classId + "@" + propId;
                List<AtomDataRolePermissionDto> permission = dataRolePermissionDto.getPermissions();
                Iterator var29 = permission.iterator();

                while(true) {
                    AtomDataRolePermissionDto item;
                    ArrayList list;
                    String userId;
                    Iterator var30;
                    do {
                        do {
                            if (!var29.hasNext()) {
                                continue label132;
                            }

                            item = (AtomDataRolePermissionDto)var29.next();
                            Set<String> roleIds = item.getRoleIds();
                            if (item.getInheritRoleIds() != null) {
                                roleIds.removeAll(item.getInheritRoleIds());
                            }

                            if (dataRolePermissionDto.getIsEncryption() == 0 || roleIds != null && roleIds.size() > 0) {
                                list = new ArrayList();
                                if (dataRolePermissionDto.getIsEncryption() == 0) {
                                    PermissionDataRole atomRole = new PermissionDataRole();
                                    atomRole.setDataId(classPropId);
                                    atomRole.setRoleId("all");
                                    atomRole.setIdType(IDTYPE.FIELD.getName());
                                    atomRole.setOp(item.getOp());
                                    if (!list.contains(atomRole)) {
                                        list.add(atomRole);
                                    }
                                }

                                PermissionDataRole atomRole;
                                for(var30 = roleIds.iterator(); var30.hasNext(); result.add("dataId:" + atomRole.getDataId() + "_roleId:" + userId)) {
                                    userId = (String)var30.next();
                                    atomRole = new PermissionDataRole();
                                    atomRole.setDataId(classPropId);
                                    atomRole.setRoleId(userId);
                                    atomRole.setIdType(IDTYPE.FIELD.getName());
                                    atomRole.setOp(item.getOp());
                                    if (!list.contains(atomRole)) {
                                        list.add(atomRole);
                                    }
                                }

                                try {
                                    this.permissionDataRoleDao.batchAdd(list);
                                } catch (DuplicateKeyException var18) {
//                                    log.error("addDataPermissionByDataId duplicate roleId {}", var18.getMessage());
                                }
                            }
                        } while(item.getUserIds() == null);
                    } while(item.getUserIds().size() <= 0);

                    list = new ArrayList();

                    PermissionDataUser atomUser;
                    for(var30 = item.getUserIds().iterator(); var30.hasNext(); result.add("dataId:" + atomUser.getDataId() + "_userId:" + userId)) {
                        userId = (String)var30.next();
                        atomUser = new PermissionDataUser();
                        atomUser.setDataId(classPropId);
                        atomUser.setUserId(userId);
                        atomUser.setIdType(IDTYPE.FIELD.getName());
                        atomUser.setOp(item.getOp());
                        if (!list.contains(atomUser)) {
                            list.add(atomUser);
                        }
                    }

                    try {
                        this.permissionDataUserDao.batchAdd(list);
                    } catch (DuplicateKeyException var17) {
//                        log.error("addDataPermissionByDataId duplicate userId {}", var17.getMessage());
                    }
                }
            }
        }

        return result;
    }
}
